package logica.pessoa;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import util.Endereco;

import logica.util.GeradorDeCodigo;

/**
 * Objeto mais generico para representar pessoas em todo o Sistema, quer
 * funcionarios, quer clientes.
 * @author Equipe Localisa (Usa quem precisa!)
 */
public class Pessoa implements Serializable{

	private transient static final long serialVersionUID = 1L;
	protected String nome;
	protected String telefone;
	protected String email;
	protected Endereco endereco;
	protected int matricula;

	
	public Pessoa(){
		
		this.nome = null;
		this.telefone = null;
		this.email = null;
		this.endereco = null;
		this.matricula = GeradorDeCodigo.getCodigo();
	}

	/**
	 * @return A matricula da pessoa no sistema
	 */
	public int getMatricula(){
		return this.matricula;
	}
	
	/**
	 * @return O endereco da pessoa
	 */
	public Endereco getEndereco() {
		return endereco;
	}

	/**
	 * Muda o endereco da pessoa
	 * @param endereco O novo endereco
	 * @throws Exception Se o novo endereco for nulo
	 */
	public void setEndereco(Endereco endereco) throws Exception {
		if (endereco == null) {
			throw new Exception("\n\t<Endereco invalido!>");
		}
		this.endereco = endereco;
	}
	
	
	/**
	 * @return O telefone da pessoa
	 */
	public String getTelefone() {
		return telefone;
	}

	/**
	 * Muda o telefone da pessoa
	 * @param telefone O novo telefone
	 * @throws Exception Se o novo telefone for invalido (nao estiver
	 * de acordo com o formato especificado no sistema)
	 */
	public void setTelefone(String telefone) throws Exception {
		if (! validaTelefone(telefone)) {
			throw new Exception("\n\t<Telefone invalido!>");
		}
		this.telefone = telefone;
	}


	/**
	 * @return O nome da pessoa
	 */
	public String getNome() {
		return nome;
	}
	
	
	/**
	 * Muda o nome da pessoa
	 * @param nome O novo nome
	 * @throws Exception Se o novo nome nao for valido (nao estiver
	 * de acordo com o formato especificado no sistema)
	 */
	public void setNome(String nome) throws Exception {
		if (! validaNome(nome)) {
			throw new Exception("\n\t<Nome invalido!>");
		}
		this.nome = nome;
		
	}

	/**
	 * @return O email da pessoa
	 */
	public String getEmail() {
		return email;
	}

	/**
	 * Muda o email da pessoa
	 * @param O email da pessoa
	 * @throws Exception Se o novo email nao for valido (nao estiver
	 * de acordo com o formato especificado no sistema) 
	 * 
	 */
	public void setEmail(String email) throws Exception {
		if (! validaEmail(email)) {
			throw new Exception("\n\t<Email invalido!>");
		}
		this.email = email;
	}

        /**
         * Valida o telefone, verificando se ele obedece o padrao.
         * @param O telefone recebido como parametro
         */
	private boolean validaTelefone(String telefone) {
		
		if (telefone == null || telefone.trim().isEmpty()) {
			return false;
		}
		
		Pattern ptel = Pattern.compile("\\([0-9]{2}\\)\\s[0-9]{4}([-])?[0-9]{4}");
		
		Matcher mtel = ptel.matcher(telefone);
		
		if (! mtel.matches()) {
			return false;
		}
		
		String dddEscolhido = telefone.substring(1, 3);
		
		if (! hasDDD(dddEscolhido)) {
			return false;
		}
		
		return true;
		
	}

        /**
         * Valida o nome, verificando se ele obedece o padrao.
         * @param O nome recebido como parametro
         */
	private boolean validaNome(String nome) {
		
		if (nome == null || nome.trim().isEmpty()) {
			return false;
		}
		
		Pattern pNome = Pattern.compile("([a-zA-Z]+([\\s][a-zA-Z]+)?){9,}");
			
		Matcher mNome = pNome.matcher(nome);
			
		return mNome.matches();
	}

	
        /**
         * Valida o email, verificando se ele obedece o padrao.
         * @param O email recebido como parametro
         */
	private boolean validaEmail(String email){
		
		if (email == null || email.trim().isEmpty()) {
			return false;
		}
		
		Pattern pEmail = Pattern.compile("([a-z]+([\\._-a-z0-9]+)?)+@[a-z]+(\\.[a-z]{2,})+");
		
		Matcher mEmail = pEmail.matcher(email);
		
		return mEmail.matches();	
	}

        /**
         * Valida o ddd, verificando se ele obedece o padrao.
         * @param O ddd recebido como parametro
         */
	private static boolean hasDDD(String dddEscolhido){
		
		String ddd [] = {"11", "12", "13", "14", "15", "16", "17", "18", "19", "21", "22", "24", "27", "28", "31", "32", "33", "34", "37", "38", "41", "42", "43", "44", "45", "46", "47", "48", "49", "51", "53", "54", "55", "61", "62", "63", "64", "65", "66", "67", "68", "69", "71", "73", "74", "75", "77", "79", "81", "82", "83", "84", "85", "86", "87", "88", "89", "91", "92", "93", "94", "95", "96", "97", "98", "99"};
		ArrayList <String> DDD = new ArrayList <String> ();
		
		for (int i =0; i < ddd.length; i++){
			DDD.add(ddd[i]);
		}
		
		return DDD.contains(dddEscolhido);
	}

	/**
	 * Analisa string para verificar existencia de digitos, apenas
	 * @param String string
	 * @return boolean true se a string for composta apenas de digitos
	 */
	public static boolean stringSoTemDigito(String string){

		for (int i =0; i < string.length(); i++){
			char caracter = string.charAt(i);
		
			if ( ! Character.isDigit(caracter))
				return false;
		}	
		return true;	
	}	
}